package com.kalvan.admin.gateway.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.extra.validation.BeanValidationResult;
import cn.hutool.extra.validation.ValidationUtil;
import com.demo.enums.mq.MqTopicEnum;
import com.github.pagehelper.Page;
import com.kalvan.admin.annotation.ParamsDecrypted;
import com.kalvan.admin.annotation.Permission;
import com.kalvan.admin.annotation.SysLog;
import com.kalvan.admin.excel.ExcelUtil;
import com.kalvan.admin.gateway.service.AppInfoService;
import com.kalvan.admin.log.LogType;
import com.kalvan.admin.valid.Add;
import com.kalvan.admin.valid.Edit;
import com.kalvan.client.context.RequestContextHolder;
import com.kalvan.client.exception.BizException;
import com.kalvan.client.model.WebResponse;
import com.kalvan.commons.constant.AdminContextCacheKey;
import com.kalvan.commons.constant.AdminReturnCode;
import com.kalvan.commons.constant.LogGroup;
import com.kalvan.commons.db.gateway.model.AppInfo;
import com.kalvan.commons.dto.gateway.AppInfoImport;
import com.kalvan.db.mybatis.PageInfo;
import com.kalvan.mq.MqUtil;
import com.kalvan.web.controller.BaseController;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * app信息Controller
 *
 * @author kalvan
 */
@SysLog(group = LogGroup.APP_INFO)
@RestController
@RequestMapping("gateway/appinfo")
@Slf4j
public class AppInfoController extends BaseController {
    @Resource
    AppInfoService appInfoService;

    /**
     * 分页查询
     *
     * @param params 查询参数
     * @return R
     */
    @PostMapping("list")
    @Permission("admin:gateway:appinfo:list")
    public WebResponse list(PageInfo pageInfo, @RequestParam Map<String, Object> params) {
        Page<AppInfo> data = appInfoService.queryPage(pageInfo, params);
        return WebResponse.buildSuccess().putPage(data);
    }

    /**
     * 根据主键查询详情
     *
     * @param id 主键
     * @return R
     */
    @GetMapping("info/{id}")
    @Permission("admin:gateway:appinfo:info")
    public WebResponse info(@PathVariable("id") Long id) {
        AppInfo appInfo = appInfoService.findById(id);
        if (appInfo == null) {
            throw new BizException(AdminReturnCode.REQUEST_ILLEGAL);
        }
        return WebResponse.buildSuccess().putData(appInfo);
    }

    private static final int DOWNLOAD_MAX_COUNT = 20000;

    /**
     * 下载
     *
     * @param params   查询参数
     * @param response response
     * @throws Exception 抛出异常拦截器统一处理
     */
    @PostMapping("download")
    @Permission("admin:gateway:appinfo:download")
    public void download(@RequestParam Map<String, Object> params, HttpServletResponse response) throws Exception {
        PageInfo pageInfo = new PageInfo();
        pageInfo.setPage(1);
        pageInfo.setLimit(DOWNLOAD_MAX_COUNT);
        Page<AppInfo> data = appInfoService.queryPage(pageInfo, params);
        String filename = "app信息";
        if (data.getTotal() > DOWNLOAD_MAX_COUNT) {
            throw new BizException(AdminReturnCode.PARAM_REGION_OVER.formatDesc("下载条数", DOWNLOAD_MAX_COUNT));
        }
        filename = filename + DatePattern.PURE_DATETIME_MS_FORMAT.format(DateUtil.date());
        ExcelUtil.download(filename, response, AppInfo.class, data);
    }

    /**
     * 新增app信息
     *
     * @param appInfoImport appInfoImport
     * @return R
     */
    @SysLog(remark = "新增app信息", type = LogType.ADD)
    @PostMapping("add")
    @Permission("admin:gateway:appinfo:add")
    public WebResponse add(@Validated({Add.class}) AppInfoImport appInfoImport) {
        appInfoService.add(BeanUtil.toBean(appInfoImport, AppInfo.class));
        return WebResponse.buildSuccess();
    }

    /**
     * app信息导入模板下载
     *
     * @param response response
     * @throws Exception 抛出异常拦截器统一处理
     */
    @GetMapping("downloadTemplate")
    @Permission("admin:gateway:appinfo:upload")
    public void downloadTemplate(HttpServletResponse response) throws Exception {
        ExcelUtil.downloadTemplate(templateRootPath + "com.kalvan/admin/app信息-模板.xls", response);
    }

    /**
     * 导入app信息
     *
     * @param file file
     * @return R
     */
    @SysLog(remark = "导入app信息", type = LogType.IMPORT)
    @PostMapping("upload")
    @Permission("admin:gateway:appinfo:upload")
    @ParamsDecrypted(required = false)
    public WebResponse upload(@RequestParam MultipartFile file) throws Exception {
        List<AppInfoImport> importList = ExcelUtil.importExcel(file, 1, 1, AppInfoImport.class);
        for (AppInfoImport appInfoImport : importList) {
            BeanValidationResult validate = ValidationUtil.warpValidate(appInfoImport, Add.class);
            if (!validate.isSuccess()) {
                throw new BizException(AdminReturnCode.PARAM_ILLEGAL.formatDesc(CollectionUtil.join(validate.getErrorMessages(), ",")));
            }
            appInfoService.add(BeanUtil.toBean(appInfoImport, AppInfo.class));
        }
        return WebResponse.buildSuccess(AdminReturnCode.SUCCESS_IMPORT.getFormatDesc(importList.size()));
    }

    /**
     * 修改app信息
     *
     * @param appInfoImport appInfoImport
     * @return R
     */
    @SysLog(remark = "修改app信息", type = LogType.EDIT)
    @PostMapping("edit")
    @Permission("admin:gateway:appinfo:edit")
    public WebResponse edit(@Validated({Edit.class}) AppInfoImport appInfoImport) {
        if (appInfoImport.getId() == null) {
            return WebResponse.buildFail(AdminReturnCode.REQUEST_ILLEGAL.getDesc());
        }
        appInfoService.edit(BeanUtil.toBean(appInfoImport, AppInfo.class));
        return WebResponse.buildSuccess();
    }

    /**
     * 根据主键删除app信息
     *
     * @param ids ids
     * @return R
     */
    @SysLog(remark = "删除app信息", type = LogType.DELETE)
    @PostMapping("delete")
    @Permission("admin:gateway:appinfo:delete")
    public WebResponse delete(Long[] ids) {
        if (ArrayUtils.isEmpty(ids)) {
            return WebResponse.buildFail(AdminReturnCode.REQUEST_ILLEGAL.getDesc());
        }
        int num = appInfoService.deleteBatch(ids);
        return WebResponse.buildSuccess(AdminReturnCode.SUCCESS_DELETE.getFormatDesc(num));
    }

    @SysLog(remark = "审核app信息", type = LogType.AUDITING)
    @PostMapping("auditing")
    @Permission("admin:gateway:appinfo:auditing")
    public WebResponse auditing(Long[] ids, boolean pass) {
        if (ArrayUtils.isEmpty(ids)) {
            return WebResponse.buildFail(AdminReturnCode.REQUEST_ILLEGAL.getDesc());
        }
        int num = appInfoService.auditingBatch(ids, pass);
        //更新缓存
        List<String> appIds = (List) RequestContextHolder.getContext().get(AdminContextCacheKey.APP_IDS);
        for (String appId : appIds) {
            updateCache(appId);
        }
        return WebResponse.buildSuccess(AdminReturnCode.SUCCESS_AUDITING.getFormatDesc(num));
    }

    @Permission("admin:gateway:appinfo:updateCache")
    @PostMapping("updateCache")
    public WebResponse updateCache(String appId) {
        MqUtil.getProducer().sendAsyncMessage(MqTopicEnum.TAG_CACHE_GATEWAY_APP.topic,
                MqTopicEnum.TAG_CACHE_GATEWAY_APP.tag, System.currentTimeMillis() + "", appId);
        return WebResponse.buildSuccess();
    }

}
